package io.github.eric.urpc.core.handler;

import io.github.eric.urpc.core.config.AbstractContext;
import io.github.eric.urpc.core.exception.UrpcMsgEncException;
import io.github.eric.urpc.core.rpc.Message;
import io.github.eric.urpc.core.serializer.Serializer;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;

import java.nio.charset.StandardCharsets;

@ChannelHandler.Sharable
public class ProtoEncoder extends MessageToByteEncoder<Message> {
	private final AbstractContext abstractContext;

	public ProtoEncoder(AbstractContext abstractContext) {
		this.abstractContext = abstractContext;
	}

	@Override
//	@SuppressWarnings({"unchecked", "rawtypes"})
	protected void encode(ChannelHandlerContext ctx, Message msg,
	                      ByteBuf out) throws Exception {
		if (msg == null) {
			return;
		}

		try {
			msg.setSendAt(System.currentTimeMillis());

			//msg class name
			byte[] clzBytes = msg.getClass().getName().getBytes(StandardCharsets.UTF_8);
			out.writeShort(clzBytes.length);
			out.writeBytes(clzBytes);

			//byte[] payload
			byte[] payload = Serializer.Json.getSerializer().serialize(msg);
			out.writeBytes(payload);

		} catch (Exception e) {
			abstractContext.getLogger().error("[urpc] message encode error, don't send this rpc message and drop it", e);
			throw new UrpcMsgEncException(e);
		}
	}
}
